#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include "RingQueue.hpp"
#include "sem.hpp"

using namespace MySem;

void *consumerRun(void *args)
{
    RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);
    int data = 0;
    while (true)
    {
        sleep(4);
        // 1. 消费任务
        rq->pop(&data);

        // 2. 处理任务 -- 处理任务的时候，这个任务，已经被拿到线程的上下文中了,不属于队列了
        std::cout << "消费了一个任务" << data << std::endl;
    }
}


int data = 1;
void *producorRun(void *args)
{
    RingQueue<int> *rq = static_cast<RingQueue<int> *>(args);
    while (true)
    {
        // sleep(1);
        //  1. 获得任务
        std::cout << "生产了一个任务: " << data << std::endl;

        // 2. 生产任务
        rq->emplace(data++);
    }
}

// test for 多生产，多消费
int main()
{
    // 创建阻塞队列
    RingQueue<int> *rq = new RingQueue<int>();

    // 创建生产者和消费者---线程模拟
    pthread_t consumer[3], producer[5];
    pthread_create(consumer, nullptr, consumerRun, rq);
    pthread_create(consumer + 1, nullptr, consumerRun, rq);
    pthread_create(consumer + 2, nullptr, consumerRun, rq);
    pthread_create(producer, nullptr, producorRun, rq);
    pthread_create(producer + 1, nullptr, producorRun, rq);
    pthread_create(producer + 2, nullptr, producorRun, rq);
    pthread_create(producer + 3, nullptr, producorRun, rq);
    pthread_create(producer + 4, nullptr, producorRun, rq);

    pthread_join(consumer[0], nullptr);
    pthread_join(consumer[1], nullptr);
    pthread_join(consumer[2], nullptr);

    pthread_join(producer[0], nullptr);
    pthread_join(producer[1], nullptr);
    pthread_join(producer[2], nullptr);
    pthread_join(producer[3], nullptr);
    pthread_join(producer[4], nullptr);
    return 0;
}

// test for 单生产消费
// int main()
//{
//    // 创建阻塞队列
//    RingQueue<int>* rq = new RingQueue<int>();
//
//    // 创建生产者和消费者---线程模拟
//    pthread_t consumer, producer;
//    pthread_create(&consumer, nullptr, consumerRun, rq);
//    pthread_create(&producer, nullptr, producorRun, rq);
//
//
//    pthread_join(consumer, nullptr);
//    pthread_join(producer, nullptr);
//    return 0;
//}